package com.example.smartmedicalsystem.controller;

import com.example.smartmedicalsystem.entity.*;
import com.example.smartmedicalsystem.repository.*;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/patient")
@RequiredArgsConstructor
public class PatientController {

    private final UserRepository userRepository;
    private final DoctorRepository doctorRepository;
    private final ScheduleRepository scheduleRepository;
    private final AppointmentRepository appointmentRepository;
    private final DepartmentRepository departmentRepository;
    private final PasswordEncoder passwordEncoder;
    private final MedicineRepository medicineRepository;
    private final PatientInventoryRepository patientInventoryRepository;
    /**
     * 患者注册接口（无需登录调用）
     */
    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody User user) {
        if (userRepository.findByUsername(user.getUsername()) != null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("用户名已存在");
        }
        user.setRole(User.Role.PATIENT);
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        User savedUser = userRepository.save(user);
        return ResponseEntity.ok(savedUser);
    }

    /**
     * 获取所有科室（对患者开放）
     */
    @GetMapping("/departments")
    public ResponseEntity<List<Department>> getAllDepartmentsForPatient() {
        List<Department> departments = departmentRepository.findAll();
        return ResponseEntity.ok(departments);
    }

    /**
     * 根据科室ID获取排班记录
     */

    @PostMapping("/purchase")
    public ResponseEntity<?> purchaseMedicine(Authentication authentication,
                                              @RequestParam Long medicineId,
                                              @RequestParam Integer quantity) {
        // 获取当前患者
        User patient = userRepository.findByUsername(authentication.getName());

        // 查询药品
        Medicine medicine = medicineRepository.findById(medicineId)
                .orElseThrow(() -> new RuntimeException("药品不存在"));

        // 库存检查
        if (medicine.getStock() < quantity) {
            return ResponseEntity.badRequest().body(medicine.getName() + "库存不足");
        }

        // 减少库存
        medicine.setStock(medicine.getStock() - quantity);
        medicineRepository.save(medicine);

        // 添加患者背包
        PatientInventory inventory = new PatientInventory();
        inventory.setPatient(patient);
        inventory.setMedicine(medicine);
        inventory.setQuantity(quantity);
        patientInventoryRepository.save(inventory);

        return ResponseEntity.ok().build();
    }
    @GetMapping("/schedules/byDepartment")
    public ResponseEntity<?> getSchedulesByDepartment(@RequestParam Long departmentId) {
        List<Schedule> allSchedules = scheduleRepository.findAll();
        List<Schedule> filtered = allSchedules.stream()
                .filter(sch -> sch.getDoctor() != null &&
                        sch.getDoctor().getDepartment() != null &&
                        sch.getDoctor().getDepartment().getId().equals(departmentId))
                .collect(Collectors.toList());
        if(filtered.isEmpty()){
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("该科室暂无排班");
        }
        return ResponseEntity.ok(filtered);
    }

    /**
     * 获取当前患者的预约记录（包含病历信息）
     */
    @GetMapping("/appointments")
    public ResponseEntity<?> getAppointments(Authentication authentication) {
        String username = authentication.getName();
        User patient = userRepository.findByUsername(username);
        // 使用 join fetch 查询关联的 medicalRecord
        List<Appointment> appointments = appointmentRepository.findByPatientWithMedicalRecord(patient);
        return ResponseEntity.ok(appointments);
    }

    /**
     * 患者预约接口：通过排班ID预约
     */
    @PostMapping("/appointments")
    public ResponseEntity<?> bookAppointment(@RequestParam Long scheduleId,
                                             Authentication authentication) {
        User patient = userRepository.findByUsername(authentication.getName());
        Schedule schedule = scheduleRepository.findById(scheduleId)
                .orElseThrow(() -> new RuntimeException("排班不存在"));
        Doctor doctor = schedule.getDoctor();
        if (doctor == null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("该排班无关联医生");
        }
        // 检查是否已有该排班的预约（防止重复预约）
        List<Appointment> existing = appointmentRepository.findByPatientWithMedicalRecord(patient)
                .stream()
                .filter(app -> app.getSchedule().getId().equals(scheduleId))
                .collect(Collectors.toList());
        if (!existing.isEmpty()) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("您已预约该班次");
        }
        Appointment appointment = new Appointment();
        appointment.setPatient(patient);
        appointment.setDoctor(doctor);
        appointment.setSchedule(schedule);
        appointment.setStatus(Appointment.Status.PENDING);
        Appointment savedAppointment = appointmentRepository.save(appointment);
        return ResponseEntity.ok(savedAppointment);
    }
    @GetMapping("/appointment/{id}")
    public ResponseEntity<?> getAppointment(@PathVariable Long id) {
        // 这里采用默认加载方式，如果需要可使用 join fetch 确保 medicalRecord 加载
        Appointment appointment = appointmentRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("预约不存在"));
        return ResponseEntity.ok(appointment);
    }
    @GetMapping("/inventory")
    public List<PatientInventory> getInventory(Authentication authentication) {
        User patient = userRepository.findByUsername(authentication.getName());
        return patientInventoryRepository.findByPatient(patient);
    }

}
